package cn.lg.soar.system.auth.client;

import cn.lg.soar.common.util.BeanCopier;
import cn.lg.soar.core.annotations.ApiClient;
import cn.lg.soar.system.api.constant.ModuleConst;
import cn.lg.soar.system.api.model.AuthOrg;
import cn.lg.soar.system.api.model.OrgDTO;
import cn.lg.soar.system.api.service.IOrgApi;
import cn.lg.soar.system.auth.entity.Org;
import cn.lg.soar.system.auth.entity.Post;
import cn.lg.soar.system.auth.model.UserOrgItemVO;
import cn.lg.soar.system.auth.service.IOrgService;
import cn.lg.soar.system.auth.service.IPostService;
import cn.lg.soar.system.auth.service.UserOrgService;
import cn.lg.soar.system.config.AuthCacheKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author luguoxiang
 * @date 2022/1/3
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@ApiIgnore
@ApiClient("boot")
@RestController
@RequestMapping(ModuleConst.CLIENT_PATH + "/org")
public class OrgApiClient implements IOrgApi {

    @Autowired
    private IOrgService service;
    @Autowired
    private IPostService postService;
    @Autowired
    private UserOrgService userOrgService;

    private final static BeanCopier<Org, OrgDTO> ENTITY_TO_DTO = BeanCopier.create(Org.class, OrgDTO.class);

    @GetMapping("codesByUserId")
    @Override
    public List<Long> idsByUserId(@RequestParam Long userId) {
        return userOrgService.getOrgIds(userId);
    }

    @GetMapping("listByIds")
    @Override
    public List<OrgDTO> listByIds(@RequestParam List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return ENTITY_TO_DTO.convertBatch(service.listByIds(ids)).collect(Collectors.toList());
    }

    @GetMapping("getById")
    @Override
    public OrgDTO getById(@RequestParam Long id) {
        return ENTITY_TO_DTO.convertNullable(service.getById(id));
    }

    @GetMapping("ancestorLink")
    @Override
    public List<OrgDTO> ancestorLink(@RequestParam Long id) {
        Org org = service.getById(id);
        List<Org> list = service.getAncestorList(org.getLeftNo(), org.getRightNo());
        list.add(list.size(), org);
        return ENTITY_TO_DTO.convertBatch(list).collect(Collectors.toList());
    }

    @GetMapping("listByUserId")
    @Override
    public List<OrgDTO> listByUserId(@RequestParam("userId") Long userId) {
        List<Org> list = service.listByUserId(userId);
        return ENTITY_TO_DTO.convertBatch(list).collect(Collectors.toList());
    }

    @GetMapping("userOrgList")
    @Override
    public List<AuthOrg> userOrgList(@RequestParam("userId") Long userId) {
        List<UserOrgItemVO> itemVOS = userOrgService.getOrgs(userId);
        Set<Long> orgIds = new HashSet<>(itemVOS.size());
        Set<Long> postIds = new HashSet<>(itemVOS.size());
        for (UserOrgItemVO org : itemVOS) {
            orgIds.add(org.getOrgId());
            postIds.add(org.getPostId());
        }

        Map<Long, Org> orgMap = service.listByIds(orgIds, AuthCacheKey.ORG_BY_ID)
                .stream()
                .collect(Collectors.toMap(Org::getId, x -> x));
        Map<Long, Post> postMap = postService.listByIds(postIds, AuthCacheKey.POST_BY_ID)
                .stream()
                .collect(Collectors.toMap(Post::getId, x -> x));

        return itemVOS.stream().map(x -> {
            AuthOrg authOrg = new AuthOrg();
            authOrg.setMain(x.getMain());

            Long orgId = x.getOrgId();
            Org org = orgMap.computeIfAbsent(orgId, k -> new Org());
            authOrg.setId(orgId);
            authOrg.setType(org.getType());
            authOrg.setName(org.getName());
            authOrg.setAlias(org.getAlias());

            Post post = postMap.computeIfAbsent(x.getPostId(), k -> new Post());
            authOrg.setPostId(x.getPostId());
            authOrg.setPostName(post.getName());
            authOrg.setPostAlias(post.getAlias());

            return authOrg;
        }).collect(Collectors.toList());
    }

}
